package com.boluo.business.service.impl;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.boluo.business.domain.BusAppointment;
import com.boluo.business.mapper.BusAppointmentMapper;
import com.boluo.business.service.IBusAppointmentService;
import com.boluo.common.constant.BusinessConstants;
import com.boluo.common.utils.CarUtils;
import com.boluo.common.utils.DateUtils;
import com.boluo.common.utils.PhoneUtils;
import com.boluo.common.utils.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.boluo.business.mapper.BusStatementMapper;
import com.boluo.business.domain.BusStatement;
import com.boluo.business.service.IBusStatementService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;

/**
 * 结算单Service业务层处理
 * 
 * @author 菠萝
 * @date 2023-04-13
 */
@Service
public class BusStatementServiceImpl implements IBusStatementService 
{
    @Resource
    private BusStatementMapper busStatementMapper;

    @Resource
    private IBusAppointmentService busAppointmentService;

    /**
     * 查询结算单
     * 
     * @param id 结算单主键
     * @return 结算单
     */
    @Override
    public BusStatement selectBusStatementById(Long id)
    {
        return busStatementMapper.selectBusStatementById(id);
    }

    /**
     * 查询结算单列表
     * 
     * @param busStatement 结算单
     * @return 结算单
     */
    @Override
    public List<BusStatement> selectBusStatementList(BusStatement busStatement)
    {
        busStatement.setIsDelete(BusinessConstants.STATEMENT_STATUS_NOT_DEL);
        return busStatementMapper.selectBusStatementList(busStatement);
    }

    /**
     * 新增结算单
     * 
     * @param busStatement 结算单
     * @return 结果
     */
    @Override
    @Transactional
    public int insertBusStatement(BusStatement busStatement)
    {
        // 参数校验 appointmentId 是否存在
        if (Objects.nonNull(busStatement.getAppointmentId())) {

            // 通过预约生成结算单
            BusAppointment appointment = busAppointmentService.selectBusAppointmentById(busStatement.getAppointmentId());
            //   这里要做预约单页面什么状态的校验
            int status = appointment.getStatus();
            Assert.state(status == BusinessConstants.APPOINTMENT_STATUS_SETTLED
                    || status == BusinessConstants.APPOINTMENT_STATUS_ARRIVED
                    || status == BusinessConstants.APPOINTMENT_STATUS_PAYED,"当前状态无法结算");

            // 设置预约单状态为 已结算
            appointment.setStatus(BusinessConstants.APPOINTMENT_STATUS_SETTLED);
            // 修改预约单状态为 已结算
            busAppointmentService.updateStatus(appointment.getId(),appointment.getStatus());

            busStatement.setCustomerName(appointment.getCustomerName());
            busStatement.setCustomerPhone(appointment.getCustomerPhone());
            busStatement.setServiceType(appointment.getServiceType());
            busStatement.setLicensePlate(appointment.getLicensePlate());
            busStatement.setActualArrivalTime(appointment.getActualArrivalTime());
            busStatement.setInfo(appointment.getInfo());
            busStatement.setCarSeries(appointment.getCarSeries());

        } else{

            //   校验除了 appointmentId外其他数据的校验
            // 使用 了API 注解校验 加自定义校验
            Assert.noNullElements(Arrays.asList(
                    busStatement.getCustomerPhone(),busStatement.getLicensePlate(),
                    busStatement.getActualArrivalTime(),busStatement.getCarSeries(),
                    busStatement.getCustomerName(),busStatement.getServiceType()),"非法数据");

            Assert.state(PhoneUtils.isPhoneNumber(busStatement.getCustomerPhone()),"手机号码格式错误");
            Assert.state(CarUtils.isLicensePlate(busStatement.getLicensePlate()),"车牌号格式错误");
        }



        // 登录的用户名(通过安全框架工具类获取 SecurityUtils)
//        busStatement.setCreateBy(SecurityUtils.getUsername());
        // 设置结算单状态
        busStatement.setStatus(BusinessConstants.STATEMENT_STATUS_CONSUMER);
        // 设置是否删除  0
        busStatement.setIsDelete(BusinessConstants.STATEMENT_STATUS_NOT_DEL);
        // 设置创建时间
        busStatement.setCreateTime(DateUtils.getNowDate());
        return busStatementMapper.insertBusStatement(busStatement);
    }

    /**
     * 修改结算单
     * 
     * @param busStatement 结算单
     * @return 结果
     */
    @Override
    public int updateBusStatement(BusStatement busStatement)
    {
        Assert.notNull(busStatement.getId(),"修改的id不能为空");
        // 通过id 获取数据库的信息
        BusStatement originBusStatement = busStatementMapper.selectBusStatementById(busStatement.getId());
        Assert.notNull(originBusStatement,"非法id");

        // 校验状态
        Assert.state(originBusStatement.getStatus() == BusinessConstants.STATEMENT_STATUS_CONSUMER,"该结算单已支付不能修改");
        // 校验手机号码
        Assert.state(PhoneUtils.isPhoneNumber(busStatement.getCustomerPhone()),"手机号码格式错误");
        // 校验车牌号
        Assert.state(CarUtils.isLicensePlate(busStatement.getLicensePlate()),"车牌号格式错误");

        return busStatementMapper.updateBusStatement(busStatement);
    }

    /**
     * 批量删除结算单
     * 
     * @param id 需要删除的结算单主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementByIds(Long id)
    {
        // 参数校验
        Assert.notNull(id,"要删除的id 不能为空");
        BusStatement busStatement = busStatementMapper.selectBusStatementById(id);
        Assert.notNull(busStatement,"要删除的id不存在");
        Assert.state(busStatement.getStatus()==BusinessConstants.STATEMENT_STATUS_PRICE,"客户没有结账不能删除");

        // 设置逻辑删除
        busStatement.setIsDelete(BusinessConstants.STATEMENT_STATUS_IS_DEL);
        return busStatementMapper.updateBusStatement(busStatement);
    }

    /**
     * 删除结算单信息
     * 
     * @param id 结算单主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementById(Long id)
    {
        return busStatementMapper.deleteBusStatementById(id);
    }

    @Override
    public BusStatement selectByAppointmentId(Long appointmentId) {
        Assert.notNull(appointmentId,"预约单id 不能为空");
        return busStatementMapper.selectByAppointmentId(appointmentId);
    }
}
